package model;

import java.util.Timer;
import java.util.TimerTask;

import controler.CompleteLogger;
import controler.Helper;

public class EnvironmentRegulator extends Recognizable {
    /**
     * @uml.property name="aimValue"
     */
    private Double aimValue;
    /**
     * @uml.property name="environment"
     * @uml.associationEnd
     */
    private final Environment environment;

    private final Timer timer = new Timer("Valve");
    private Boolean stopped = Boolean.TRUE;
    private Double effect = Constants.ENVIRONMENT_REGULATOR_EFFECT;

    public EnvironmentRegulator(Environment environment, Integer id) {
        super(id);
        this.environment = environment;
    }

    public void reguleValue(Double aimValue) {
        this.aimValue = aimValue;
        if (!isStopped()) {
            stop();
            Helper.pause();
        }
        start();
        Regulator regulator = new Regulator();
        timer.schedule(regulator, 0, Constants.SECONDS);

        CompleteLogger.getLogger().info("Regulator of " + environment.toString() + " starts, regulating value to: " + aimValue);

    }

    public Boolean isStopped() {
        return stopped;
    }

    public void stop() {
        this.stopped = true;
        CompleteLogger.getLogger().info("Regulator of " + environment.toString() + " stop regulating value.");

    }

    private void start() {
        this.stopped = false;
    }

    public void amortize() {
        effect = effect * 0.5;
    }

    private Double getEffect() {
        return effect;
    }

    private class Regulator extends TimerTask {

        @Override
        public void run() {
            while (!isStopped()) {
                if (Math.abs(environment.getValue().getValue().doubleValue() - aimValue.doubleValue()) > 0.02) {
                    environment.modifyValue((aimValue.doubleValue() - environment.getValue().getValue().doubleValue()) * getEffect().doubleValue());
                }
                try {
                    Thread.sleep(Constants.SECONDS * 5);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

    public void repair() {

        effect = effect * 2;
        if (effect > Constants.ENVIRONMENT_REGULATOR_EFFECT) {
            effect = Constants.ENVIRONMENT_REGULATOR_EFFECT;
        }
    }
}
